#pragma once

#include "cybertron/network/Message.hpp"
#include "cybertron/network/SocketTcpClient.hpp"
#include "cybertron/network/SocketEventHandler.hpp"
#include "cybertron/network/NetworkActionExecuter.hpp"
#include "cybertron/network/MessageRouter.hpp"
#include "cybertron/core/JsonReader.hpp"
#include "cybertron/core/Log.hpp"
#include "MasterConfig.hpp"
#include <thread>

#include "Node/Master.pb.h"
using namespace cybertron;

class MasterTestClient
{
public:
	MasterTestClient();
	~MasterTestClient();
	bool initialize(int argc, char* argv[]);
	bool isLogon() { return mbLogon; }
	bool isCanSendTask() { return !mTaskId.length() == 0; }
	void test();
private:
	void zeroMembers();
	void run();
	void clearThis();
	bool Connect();
	void onDisconnected();

	
	void onServerMessage(Message& msg);
	bool processMessagesUntil(
		uint16_t* pDesiredMessageIds,
		Message* pDesiredMessages,
		size_t numDesiredMessages = 1,
		int timeoutMilliseconds = -1,
		bool msgOnebyOne = true);
	
public:
	// Register
	void sendRegisterNode();
	void onFromMasterNodeRegisterRet(cybertron::Message& msg);

	//send command
	void sendCommand2Agent();
	void onFromMasterCommand2AgentRet(cybertron::Message& msg);
	void onFromMasterGetAgentHardwareInfoRet(cybertron::Message& msg);
	void GetAgentHardwareInfo();
	//task ProAllocate
	void sendTaskProAllocate();
	void onFromMasterTaskProAllocateRet(cybertron::Message& msg);

	//task Recycle
	void sendTaskRecycleProAllocate();
	void onFromMasterTaskRecycleProAllocateRet(cybertron::Message& msg);

	//task start
	void sendTaskStart();
	void onFromMasterTaskStartRet(cybertron::Message& msg);

	//task stop
	void sendTaskStop();
	void onFromTaskStopRet(cybertron::Message& msg);

	//work node start
	void sendWorkNodeStart();
	void onFromWorkNodeStartRet(cybertron::Message& msg);

	//work node stop
	void sendWorkNodeStop();
	void onFromWorkNodeStopRet(cybertron::Message& msg);
	void onFromSyncWorkNodeDynamicConfig(cybertron::Message& msg);
	
	void onFromAgentStatusChange(cybertron::Message& msg);
	void onFromTaskStateChange(cybertron::Message& msg);
	void onFromWorkStateChange(cybertron::Message& msg);
	void onFromWorkStatusChange(cybertron::Message& msg);
	void onFromWorkProgessChange(cybertron::Message& msg);
	void onFromEndTaskReasonChange(cybertron::Message& msg);

private:
protected:
	std::shared_ptr<MasterConfig> mpConfig;
	std::string mHostIp;
	int mHostPort;
	std::shared_ptr<SocketTcpClient> mpClient;
	enum EServiceState
	{
		EServiceState_Work,
		EServiceState_Stop
	};
	std::atomic<EServiceState> mState;

	size_t mNumDesiredMessages;
	std::uint16_t* mpDesiredMessageIds;
	Message* mpDesiredMessages;
	size_t mNumReceivedDesiredMessages;
	size_t mOneLoopServerMessageCounter;


	bool mbLogon;
	string mTaskId;
};
